package org.raymond.iworks.study.netty.atguigu.nio.reactor.mainsub;

import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.*;

/**
 * @author raymond
 * @version V1.0
 * @Description: main reactor
 */
@Slf4j
public class GroupChatServer {
    private Selector aceeptSelector;
    private Selector otherSelector;

    private ServerSocketChannel serverSocketChannel;

    private ThreadPoolExecutor fixedThreadPool = new ThreadPoolExecutor(2, 2, 0, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>());

    private SubReactor subReactor;

    public static final int PORT = 6667;

    //构造器初始化成员变量
    public GroupChatServer() {
        try {
            //打开一个监听连接事件的选择器
            this.aceeptSelector = Selector.open();
            //打开一个监听非连接事件的选择器
            this.otherSelector = Selector.open();
            //打开serverSocketChannel
            this.serverSocketChannel = ServerSocketChannel.open();
            //绑定地址，端口号
            this.serverSocketChannel.bind(new InetSocketAddress("127.0.0.1", PORT));
            //设置为非阻塞
            serverSocketChannel.configureBlocking(false);
            //把通道注册到选择器中
            serverSocketChannel.register(aceeptSelector, SelectionKey.OP_ACCEPT);

            subReactor = new SubReactor(otherSelector);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 监听，并且接受客户端消息，转发到其他客户端
    public void listen(){
        try {
            while (true) {
                //获取监听的事件总数
                int count = aceeptSelector.select(2000);
                if (count > 0) {
                    Set<SelectionKey> selectionKeys = aceeptSelector.selectedKeys();
                    //获取SelectionKey集合
                    Iterator<SelectionKey> it = selectionKeys.iterator();
                    while (it.hasNext()) {
                        SelectionKey key = it.next();
                        //如果是获取连接事件
                        if (key.isAcceptable()) {
                            SocketChannel socketChannel = serverSocketChannel.accept();
                            //设置为非阻塞
                            socketChannel.configureBlocking(false);
                            //注册到非连接事件选择器中
                            socketChannel.register(otherSelector, SelectionKey.OP_READ);
                            log.info(socketChannel.getRemoteAddress() + "上线了~");
                            fixedThreadPool.execute(subReactor);
                        }
                        it.remove();
                    }
                }
            }
        } catch (Exception e) {
            log.error("{}", e.getMessage());
        }
    }

    public static void main(String[] args) throws Exception {
        GroupChatServer chatServer = new GroupChatServer();
        //启动服务器，监听
        chatServer.listen();
    }
}
